<template>
  <view class="x-upload">
    <view v-if="$slots.default" class="_slot">
      <slot />
    </view>
    <view v-else class="_content">
      <view v-for="item in tempFiles" :key="item.uuid" class="_item">
        <view class="_pic">
          <x-image :src="item.tempFilePath" />
          <view v-if="item.loading" class="_loading">上传中…</view>
          <view v-if="item.error" class="_error">上传失败</view>
          <view class="_close">
            <x-icon name="icon-025" size="20" color="#fff" @click="handleRemove(item.uuid)" />
          </view>
        </view>
      </view>
      <view v-if="isChoose" class="_item">
        <view class="_upload" @click="onChangeChoose">
          <view class="_icon">
            <x-icon name="icon-014" size="54" color="#999999"/>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
import { v4 as uuidv4 } from 'uuid';
import XIcon from '@/components/x-icon';
import XImage from '@/components/x-image';

export default {
  name: 'XUpload',
  components: {
    XIcon,
    XImage
  },
  props: {
    // 默认值
    value: {
      type: [String, Array],
      default: () => null
    },
    type: {
      type: String,
      default: 'image'
    },
    sizeType: {
      type: Array,
      default: () => ['compressed']
    },
    sourceType: {
      type: Array,
      default: () => ['album', 'camera']
    },
    extension: {
      type: Array,
      default: () => ['pdf', 'doc']
    },
    count: {
      type: Number,
      default: 9
    },
    maxDuration: {
      type: Number,
      default: 15
    },
    dir: {
      type: String,
      default: 'avatar'
    },
    camera: {
      type: String,
      default: 'back'
    },
    text: {
      type: String,
      default: ''
    },
    border: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      tempFiles: []
    };
  },
  computed: {
    styles() {
      const style = {};
      if (this.border) {
        style.border = this.border;
      }
      return style;
    },
    isChoose() {
      return this.tempFiles.length < this.count;
    }
  },
  watch: {},
  created() {

  },
  methods: {
    onChangeChoose() {
      this.$choose({
        count: this.count - this.tempFiles.length,
        maxDuration: this.maxDuration,
        camera: this.camera,
        type: this.type,
        sizeType: this.sizeType,
        sourceType: this.sourceType,
        extension: this.extension
      }).then(res => {
        this.$emit('before-upload', res, this.type);
        this.handleChooseFiles(res);
      }).catch(err => {
        console.error(err);
      });
    },
    handleChooseFiles({ tempFiles }) {
      const list = tempFiles.map(item => {
        return {
          ...item,
          url: null,
          state: 0,
          error: false,
          loading: true,
          uuid: uuidv4()
        };
      });
      this.tempFiles.push(...list);
      this.handleUpload();
    },
    // 开始上传
    handleUpload() {
      const files = this.tempFiles.filter(item => item.state === 0);
      files.forEach(item => {
        item.state = 1;
        this.$http({
          url: '/product/media/upload',
          file: item.tempFilePath,
          data: {
            mediaType: this.type === 'video' ? 2 : 1
          }
        }).then(res => {
          item.loading = false;
          item.state = 2;
          item.url = res.data.fileUrl;
          this.handleSuccess();
        }).catch(() => {
          item.state = 3;
          item.error = true;
          item.loading = false;
        });
      });
    },
    // 移除某个
    handleRemove(uuid) {
      const findIndex = this.tempFiles.findIndex(item => item.uuid === uuid);
      this.tempFiles.splice(findIndex, 1);
      this.handleSuccess();
    },
    // 同步值
    handleSuccess() {
      let url = this.tempFiles.length ? this.tempFiles[0].url : null;
      if (this.count > 1) {
        url = this.tempFiles.map(item => item.url);
        this.$emit('update:value', url.length ? url : null);
      } else {
        this.$emit('update:value', url);
      }
      this.$emit('change', url);
    }
  }
};
</script>

<style lang="scss">
  .x-upload{
    text-align: center;
    ._content{
      display: grid; gap: 10px; grid-template-columns: repeat(4, minmax(0px, 1fr));
      ._upload{ background-color: #F7F7F7; width: 150px; height: 150px; display: flex; align-items: center; justify-content: center;}
      ._pic{
        width: 150px; height: 150px; position: relative; overflow: hidden;
        ._close{ position: absolute; right: 0; top: 0; padding: 6px; width: 32px; height: 32px; display: flex; align-items: center; justify-content: center; border-radius: 50%; background-color: rgba(0, 0, 0, .8);}
        ._error,
        ._loading{ position: absolute; left: 0; top: 0; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; background-color: rgba(0, 0, 0, .5); color: #fff; font-size: 24px;}
      }
    }
  }
</style>
